home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 2000 Aladdin Enterprises. All rights reserved.
-
- This file is part of AFPL Ghostscript.
-
- AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or
- distributor accepts any responsibility for the consequences of using it, or
- for whether it serves any particular purpose or works at all, unless he or
- she says so in writing. Refer to the Aladdin Free Public License (the
- "License") for full details.
-
- Every copy of AFPL Ghostscript must include a copy of the License, normally
- in a plain ASCII text file named PUBLIC. The License grants you the right
- to copy, modify and redistribute AFPL Ghostscript, but only under certain
- conditions described in the License. Among other things, the License
- requires that the copyright notice and this notice be preserved on all
- copies.
- */
-
- /*$Id: gdevl256.c,v 1.3 2000/09/19 19:00:13 lpd Exp $ */
- /* Ghostscript driver for 256-color VGA modes with Linux and vgalib */
- /* This Driver was derived from the BGI-Driver. It was written
- only for my own purpose. I never planned to release it or send
- it to others. So, if something doesn't work, you may send
- me a short note, but don't expect me to correct it. I will
- try my very best, but i have some work to do.
-
- Ludger Kunz | ____________|Tel.: 02371/566-230
- FernUniversitaet Hagen| /| / / \ |FAX: 02371/52212
- Lehrgebiet ES | / |/ /_ \ |EMAIL:
- Frauenstuhlweg 31 | / |\ / \ |ludger.kunz@fernuni-hagen.de
- 58644 Iserlohn |/___|_\/_______\|
- */
- #include "memory_.h"
- #include "gx.h"
- #include "gxdevice.h"
- #include "gserrors.h"
-
- #include <errno.h>
- #include <vga.h>
- #include <vgagl.h>
-
- /* The color map for dynamically assignable colors. */
- #define first_dc_index 64
- private int next_dc_index;
-
- #define dc_hash_size 293 /* prime, >num_dc */
- typedef struct {
- ushort rgb, index;
- } dc_entry;
- private dc_entry dynamic_colors[dc_hash_size + 1];
-
- #define XDPI 60 /* to get a more-or-less square aspect ratio */
- #define YDPI 60
-
- #ifndef A4 /*Letter size */
- #define YSIZE (20.0 * YDPI / 2.5)
- #define XSIZE (8.5 / 11)*YSIZE /* 8.5 x 11 inch page, by default */
- #else /* A4 paper */
- #define XSIZE 8.3 /*8.27 */
- #define YSIZE 11.7 /*11.69 */
- #endif
-
-
- /* The device descriptor */
- typedef struct gx_device_lvga256 {
- gx_device_common;
- } gx_device_lvga256;
-
- #define lvga256dev ((gx_device_lvga256 *)dev)
-
- private dev_proc_open_device(lvga256_open);
- private dev_proc_close_device(lvga256_close);
- private dev_proc_map_rgb_color(lvga256_map_rgb_color);
- private dev_proc_map_color_rgb(lvga256_map_color_rgb);
- private dev_proc_fill_rectangle(lvga256_fill_rectangle);
- private dev_proc_tile_rectangle(lvga256_tile_rectangle);
- private dev_proc_copy_mono(lvga256_copy_mono);
- private dev_proc_copy_color(lvga256_copy_color);
- private dev_proc_draw_line(lvga256_draw_line);
-
- private gx_device_procs lvga256_procs =
- {
- lvga256_open,
- NULL, /* get_initial_matrix */
- NULL, /* sync_output */
- NULL, /* output_page */
- lvga256_close,
- lvga256_map_rgb_color,
- lvga256_map_color_rgb,
- lvga256_fill_rectangle,
- lvga256_tile_rectangle,
- lvga256_copy_mono,
- lvga256_copy_color,
- lvga256_draw_line
- };
-
- gx_device_lvga256 far_data gs_lvga256_device =
- {std_device_color_body(gx_device_lvga256, &lvga256_procs, "lvga256",
- 0, 0, /* width and height are set in lvga256_open */
- 1, 1, /* density is set in lvga256_open */
- /*dci_color( */ 8, 31, 4 /*) */ )
- };
-
- /* Open the LINUX driver for graphics mode */
- int
- lvga256_open(gx_device * dev)
- {
- int vgamode;
- int width, height;
-
- vga_init();
- vgamode = vga_getdefaultmode();
- if (vgamode == -1)
- vgamode = G320x200x256;
- vga_setmode(vgamode);
- gl_setcontextvga(vgamode);
- width = vga_getxdim();
- height = vga_getydim();
- dev->y_pixels_per_inch = height / 12.0;
- dev->x_pixels_per_inch = dev->y_pixels_per_inch;
- gx_device_set_width_height(dev, width, height);
- {
- int c;
-
- for (c = 0; c < 64; c++) {
- static const byte c2[10] =
- {0, 42, 0, 0, 0, 0, 0, 0, 21, 63};
-
- gl_setpalettecolor(c, c2[(c >> 2) & 9], c2[(c >> 1) & 9], c2[c & 9]);
- }
- }
- /* Initialize the dynamic color table. */
- memset(dynamic_colors, 0, (dc_hash_size + 1) * sizeof(dc_entry));
- next_dc_index = first_dc_index;
-
- return 0;
- }
-
- /* Close the LINUX driver */
- int
- lvga256_close(gx_device * dev)
- {
- vga_setmode(TEXT);
- return 0;
- }
-
- /* Map a r-g-b color to a palette index. */
- /* The first 64 entries of the color map are set */
- /* for compatibility with the older display modes: */
- /* these are indexed as 0.0.R0.G0.B0.R1.G1.B1. */
- gx_color_index
- lvga256_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g,
- gx_color_value b)
- {
- #define cv_bits(v,n) (v >> (gx_color_value_bits - n))
- ushort r5 = cv_bits(r, 5), g5 = cv_bits(g, 5), b5 = cv_bits(b, 5);
- static const byte cube_bits[32] =
- {0, 128, 128, 128, 128, 128, 128, 128, 128, 128,
- 8, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
- 1, 128, 128, 128, 128, 128, 128, 128, 128, 128,
- 9
- };
- uint cx = ((uint) cube_bits[r5] << 2) + ((uint) cube_bits[g5] << 1) +
- (uint) cube_bits[b5];
- ushort rgb;
- register dc_entry *pdc;
-
- /* Check for a color on the cube. */
- if (cx < 64)
- return (gx_color_index) cx;
- /* Not on the cube, check the dynamic color table. */
- rgb = (r5 << 10) + (g5 << 5) + b5;
- for (pdc = &dynamic_colors[rgb % dc_hash_size]; pdc->rgb != 0; pdc++) {
- if (pdc->rgb == rgb)
- return (gx_color_index) (pdc->index);
- }
- if (pdc == &dynamic_colors[dc_hash_size]) { /* Wraparound */
- for (pdc = &dynamic_colors[0]; pdc->rgb != 0; pdc++) {
- if (pdc->rgb == rgb)
- return (gx_color_index) (pdc->index);
- }
- }
- if (next_dc_index == 256) { /* No space left, report failure. */
- return gx_no_color_index;
- }
- /* Not on the cube, and not in the dynamic table. */
- /* Put in the dynamic table if space available. */
- {
- int i = next_dc_index++;
-
- pdc->rgb = rgb;
- pdc->index = i;
- gl_setpalettecolor(i, cv_bits(r, 6), cv_bits(g, 6), cv_bits(b, 6));
- return (gx_color_index) i;
- }
- }
-
- int
- lvga256_map_color_rgb(gx_device * dev, gx_color_index color,
- unsigned short prgb[3])
- {
- /* gl_getpalettecolor (color,(int *)&prgb[0],(int *)&prgb[1],(int *)&prgb[2]); */
- prgb[0] = gx_max_color_value;
- prgb[1] = gx_max_color_value;
- prgb[2] = gx_max_color_value;
- return 0;
- }
-
- /* Copy a monochrome bitmap. The colors are given explicitly. */
- /* Color = gx_no_color_index means transparent (no effect on the image). */
- int
- lvga256_copy_mono(gx_device * dev,
- const byte * base, int sourcex, int raster, gx_bitmap_id id,
- int x, int y, int w, int h,
- gx_color_index zero, gx_color_index one)
- {
- const byte *ptr_line = base + (sourcex >> 3);
- int left_bit = 0x80 >> (sourcex & 7);
- int dest_y = y, end_x = x + w;
- int invert = 0;
- int color;
-
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
- if (zero == gx_no_color_index) {
- if (one == gx_no_color_index)
- return 0;
- color = (int)one;
- } else {
- if (one == gx_no_color_index) {
- color = (int)zero;
- invert = -1;
- } else { /* Pre-clear the rectangle to zero */
- gl_fillbox(x, y, w, h, 0);
- color = (int)one;
- }
- }
- while (h--) { /* for each line */
- const byte *ptr_source = ptr_line;
- register int dest_x = x;
- register int bit = left_bit;
-
- while (dest_x < end_x) { /* for each bit in the line */
- if ((*ptr_source ^ invert) & bit) {
- gl_setpixel(dest_x, dest_y, color);
- }
- dest_x++;
- if ((bit >>= 1) == 0)
- bit = 0x80, ptr_source++;
- }
- dest_y++;
- ptr_line += raster;
- }
- return 0;
- }
-
- /* Copy a color pixel map. This is just like a bitmap, except that */
- /* each pixel takes 4 bits instead of 1 when device driver has color. */
- int
- lvga256_copy_color(gx_device * dev,
- const byte * base, int sourcex, int raster, gx_bitmap_id id,
- int x, int y, int w, int h)
- {
- fit_copy(dev, base, sourcex, raster, id, x, y, w, h);
- if (gx_device_has_color(dev)) { /* color device, four bits per pixel */
- const byte *line = base + sourcex;
-
- gl_putbox(x, y, w, h, line);
- } else { /* monochrome device: one bit per pixel */
- /* bit map is the same as lvga256_copy_mono: one bit per pixel */
- lvga256_copy_mono(dev, base, sourcex, raster, id, x, y, w, h,
- (gx_color_index) 0, (gx_color_index) 255);
- }
- return 0;
- }
-
- /* Fill a rectangle. */
- int
- lvga256_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
- gx_color_index color)
- {
- fit_fill(dev, x, y, w, h);
- gl_fillbox(x, y, w, h, color);
- return 0;
- }
-
- /* Tile a rectangle. If neither color is transparent, */
- /* pre-clear the rectangle to color0 and just tile with color1. */
- /* This is faster because of how lvga256_copy_mono is implemented. */
- /* Note that this also does the right thing for colored tiles. */
- int
- lvga256_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile,
- int x, int y, int w, int h, gx_color_index czero, gx_color_index cone,
- int px, int py)
- {
- if (czero != gx_no_color_index && cone != gx_no_color_index) {
- lvga256_fill_rectangle(dev, x, y, w, h, czero);
- czero = gx_no_color_index;
- }
- return gx_default_tile_rectangle(dev, tile, x, y, w, h, czero, cone, px, py);
- }
-
- /* Draw a line */
- int
- lvga256_draw_line(gx_device * dev, int x0, int y0, int x1, int y1,
- gx_color_index color)
- {
- gl_line(x0, y0, x1, y1, color);
- return 0;
- }
-